// ContestSample.cpp : Defines the entry point for the console application.
//
#include "ParallelTest.h"
#include <windows.h>
using namespace std;

int main(int argc, char* argv[])
{
    //Get Test Time
	long   t1=GetTickCount();
	if (argc != 4)
    {
        printf("Usage: ContestSample.exe geometry_input.txt ray_input.txt output.txt\n");
        //return 0;
    }

	//const char* geomFile = argv[1];
	//const char* rayFile = argv[2];
	//const char* outputFile = argv[3];

	const char* geomFile = "geom_few.txt";
	const char* rayFile = "ray_few.txt";
	const char* outputFile = "out_few.txt";

    // read the geometry input file
	ifstream streamGeom;
	streamGeom.open(geomFile);
	
    int numOfTriangles = 0;
	streamGeom >> numOfTriangles;

	F3d* vertexBuffer = new F3d[numOfTriangles * 3];

	for (int i = 0; i < numOfTriangles * 3; i++)
	{
		streamGeom >> vertexBuffer[i].x >> vertexBuffer[i].y >> vertexBuffer[i].z;
	}

	streamGeom.close();

    // read the ray input file
    ifstream streamRay;
	streamRay.open(rayFile);
	int numOfRays = 0;
	streamRay >> numOfRays;
	F3d* rayOrigins = new F3d[numOfRays];
	F3d* rayDirections = new F3d[numOfRays];

	for (int i = 0; i < numOfRays; i++)
	{
		streamRay >> rayOrigins[i].x >> rayOrigins[i].y >> rayOrigins[i].z;
		streamRay >> rayDirections[i].x >> rayDirections[i].y >> rayDirections[i].z; 
	}
	streamRay.close();

    // this is the container for all the output intersection points
    // here we simply use std::vector as the container but you will
    // need to change to a thread-safe container if your computing is
    // multi-threaded.
    //vector<F3d> intersectPoints;

    // now you can perform the computation of the intersection points
    // but please note that parallelism isn't the panacea. It cannot 
    // eliminate the need for a smart sequential algorithsm that reduces
    // the time complexity of the computation. One good approach is to first
    // write your program like you usually do - write a sequential version first.
    // And try your best to reduce the time complexity of your sequential algorithsm
    // e.g. if it's O(N * N), try to reduce it to O(N * logN). If it's O(N), try to
    // see if it's possible to reduce it to O(logN). When you have a good sequential 
    // algorithsm you can start thinking about where to parallelize.

	int numOfIntersectonPoints = 0;
	F3dList* pIntersectionPointList = new F3dList();
    fnComputeProcess(numOfTriangles, vertexBuffer, numOfRays, rayOrigins, rayDirections,&numOfIntersectonPoints,pIntersectionPointList);

    // now computation finishes. All the intersection points are now in the container intersectPoints.
    // before we output results, we first delete the input data that we no longer use
	delete[] rayDirections;
	delete[] rayOrigins;
	delete[] vertexBuffer;

    // we now output the results into the specified file
    ofstream streamOut;
    streamOut.open(outputFile);

    streamOut << numOfIntersectonPoints << endl;
	F3dNode* pNode = new F3dNode();
	//Output and clear the node list
    for (int i = 0; i < numOfIntersectonPoints; i++)
    {
        pNode = pIntersectionPointList->pNext;
		streamOut << pNode->pointData.x << " " << pNode->pointData.y << " " << pNode->pointData.z << endl;
		pIntersectionPointList->pNext = pNode->pNext;
		//delete(pNode);
    }
	delete(pIntersectionPointList);
	//Get Time for Test and output
	long t2=GetTickCount();
	streamOut << t2-t1 << endl;
    streamOut.close();
    // congratulations!!!
    // your program finished the intensive computation 
    // most importantly it survived and didn't crash. :)
	return 0;
}

